// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html


import CM from "../cache/CM";
import ICache from "../cache/ICache";
import { MONITOR_LIST } from "../common/Decorator";
import ResMgr from "../common/ResMgr";
import DBMgr from "../db/DBMgr";
import MsgMgr from "../event/MsgMgr";
import Global from "../Global";
import CCMP from "../object/CCMP";
import StartUp from "../StartUp";

import UIMgr from "./UIMgr";

interface UIRelatedAttr {
    uiNode:cc.Node;
    data:ICache<any>;
    attrName:string;
}


const {ccclass, property} = cc._decorator;

@ccclass
export abstract default class UINode {

    protected _autoAdaptation: boolean = true;
    protected _autoBind: boolean = true;
    protected _cameraAdaptation: boolean = false;
    protected _isSwallowTouch: boolean = true;
    protected _isNeedFocus:boolean = true;
    protected _isAddToTop:boolean = false;
    protected _isAddToBottom:boolean = false;
    protected _isClearCache:boolean = true;
    protected _isGameCamera:boolean = false;

    //是否准备好了
    private _isReady:boolean = false;
    public get ready():boolean {
        return this.node != null;
    }

    //是否显示
    private _isShow:boolean = false;
    public get isShow():boolean {
        return this._isShow;
    }

    //是否聚焦
    public get isNeedFocus():boolean {
        return this._isNeedFocus;
    }

    //预制体节点
    private _node:cc.Node = null;
    public get node():cc.Node {
        return this._node;
    }
    //名字
    public get name():string {
        let prefabPath = this.prefab();
        let array = prefabPath.split("/");
        let nameWithExt = array[array.length-1];
        let name = nameWithExt.split(".")[0];
        return name;
    }
    //是否被删除
    private _isRemove:boolean = false;
    public get isRemove():boolean {
        return this._isRemove;
    }
    private _deps = [];
    ////////////////////////////////////////////////////////////////////////////////////////////////初始化
    public init(args) {
        
        this.loadPrefab();
    }
    tick(dt) {

    }
    //加载预制体
    private loadPrefab() {
        let path = this.prefab();
        
        ResMgr.loadPrefab(path, (prefab) => {
            if (this.isRemove) { return; }
            this._node = cc.instantiate(prefab);
            let uuid = prefab._uuid;
            //this._deps = cc.assetManager.dependUtil.getDeps(uuid);
            this._deps.push(uuid);

            this._node.group = "UILayer";
            this.addToRoot(this._node);
            this._node.zIndex = this.zOrder();
            this.initProcess();
        })
    }

    private addToRoot(node) {
        if (this._isAddToTop) {
            UIMgr.ins(UIMgr).topRoot.addChild(node);
        } else if (this._isAddToBottom) {
            UIMgr.ins(UIMgr).bottomRoot.addChild(node);
        } else {
            UIMgr.ins(UIMgr).normalRoot.addChild(this._node);
        }
    }

    private initMonitor() {
        let list:[] = this[MONITOR_LIST] || [];
        for (let i = 0; i < list.length; i++) {
            list[i] && (list[i] as Function)(this);
        }
    }

    private closeMonitor() {
        let list:[] = this[MONITOR_LIST] || [];
        for (let i = 0; i < list.length; i++) {
            list[i] && (list[i] as Function)(this, null, true);
        }
    }

    onDefaultUpdateUI(uiNode:cc.Node, newVal) {
        let label = uiNode.getComponent(cc.Label);
        if (label != null) {
            label.string = newVal;
        }
    }

    //初始化流程
    private initProcess() {
        if (this._autoAdaptation) {
            this.adaptation();
        }
        if (this._autoBind) {
            this.autoBind();
        } else {
            this.manualBind();
        }
        if (this._isSwallowTouch) {
            this.swallowTouches();
        }
        this.registerEvent();
        this.initMonitor();
        this.onShowAct();
        this.onShow();
        this.isGameCamerShow(false)
        
    }

    isGameCamerShow(show){
        if(this._isGameCamera == true){
            StartUp.instance.gameCamera.node.active = show;
        }
    }

    private swallowTouches() {
        let swallowNode = new cc.Node();
        swallowNode.name = "Swallow"
        swallowNode.width = cc.winSize.width;
        swallowNode.height = cc.winSize.height;
        swallowNode.parent = this.node;
        swallowNode.zIndex = -1;
        swallowNode.addComponent(cc.BlockInputEvents);
    }

    //位置适配
    private adaptation() {
        let designSize = cc.view.getDesignResolutionSize();
        let winSize = cc.winSize;
        let widthFactor = (winSize.width/designSize.width);
        let heightFactor = (winSize.height/designSize.height);

        //this.node.x -= winSize.width/2;
        //this.node.y -= winSize.height/2;

        for (let i = 0; i < this.node.children.length; i++) {
            let child = this.node.children[i];
            let x = child.x;
            let y = child.y;

            child.x = x*widthFactor;
            child.y = y*heightFactor;

            //顶部摄像机
            if (this._cameraAdaptation) {
                if (child.x/(winSize.width/2) < -0.92) {
                    child.x = -(winSize.width/2)*0.92;
                }
                
            }
        }
    }

    /**
     * 手动绑定节点需要重写此方法
     */
    protected bindNodePath() {
        return {};
    };

    //便捷手动绑定使用节点
    protected manualBind() {
        let pathDict = this.bindNodePath();
        let keyList = Object.keys(pathDict);
        for (let i = 0; i < keyList.length; i++) {
            let name = keyList[i];
            let path = pathDict[name];
            this[name] = cc.find(path, this._node);
            this.onDefaultDealWith(this[name]);
        }
    }


    //便捷自动绑定使用节点
    protected autoBind() {
        this.loopChild(this.node);
    }
    //遍历寻找子节点
    private loopChild(parent:cc.Node) {
        if (parent == null || parent.children == null || parent.children.length == 0) { return; }
        for (let i = 0; i < parent.children.length; i++) {
            let child = parent.children[i];
            let name = child.name;
            if (name == "name" || name == "view" || name=="node") {
                name = "default_"+name;
            }
            this[name] = child;
            this.onDefaultDealWith(child);
            this.loopChild(child);
        }
    }
    //默认的节点处理
    private onDefaultDealWith(child:cc.Node) {
        let button = child.getComponent(cc.Button);
        if (button != null) {
            this.onRegisterClick(button);
        }
        let pageview = child.getComponent(cc.PageView);
        if (pageview != null) {
            this.onRegisterPageview(pageview);
        }
        let label = child.getComponent(cc.Label);
        if (label != null) {
            this.onDefaultLanguage(label);
        }

        let rich = child.getComponent(cc.RichText);
        if (rich != null) {
            this.onDefaultRichLanguage(rich);
        }
    }
    //判断label是否有直接使用language
    private onDefaultLanguage(label:cc.Label) {
        let content = label.string;
        let res = content.match("<l>\\d*</l>");
        if (res == null) { return; }
        let languageId = Number(res[0].replace("<l>", "").replace("</l>", ""));
        let str = DBMgr.data.languageDB[languageId][Global.language];
        label.string = label.string.replace(res[0], str);
        this.onDefaultLanguage(label);
    }
    //rich
    private onDefaultRichLanguage(rich:cc.RichText) {
        let content = rich.string;
        let res = content.match("<l>\\d*</l>");
        if (res == null) { return; }
        let languageId = Number(res[0].replace("<l>", "").replace("</l>", ""));
        let str = DBMgr.data.languageDB[languageId][Global.language];
        rich.string = rich.string.replace(res[0], str);
        this.onDefaultRichLanguage(rich);
    }
    //注册按钮监听
    private onRegisterClick(button:cc.Button) {
        button.node.on("click", function(evt){
            this.on_click_common(evt);
            this["on_click_"+button.node.name] && this["on_click_"+button.node.name](evt);
        }, this);
        button.node.on(cc.Node.EventType.TOUCH_START, function(evt){
            this.on_click_common_start(evt);
            this["on_click_"+button.node.name+"_start"] && this["on_click_"+button.node.name+"_start"](evt);
        }, this)
        button.node.on(cc.Node.EventType.TOUCH_CANCEL, function(evt){
            this.on_click_common_cancel(evt);
            this["on_click_"+button.node.name+"_cancel"] && this["on_click_"+button.node.name+"_cancel"](evt);
        }, this)
        button.node.on(cc.Node.EventType.TOUCH_MOVE, function(evt){
            this.on_click_common_move(evt);
            this["on_click_"+button.node.name+"_move"] && this["on_click_"+button.node.name+"_move"](evt);
        }, this)
    }
    
    //pageview监听
    private onRegisterPageview(pageView:cc.PageView) {
        pageView.node.on("page-turning", function(){
            this["on_page_turn_"+pageView.node.name] && this["on_page_turn_"+pageView.node.name](pageView);
        }, this)
    }
    private registerEvent() {
        MsgMgr.on("ON_"+this.name+"_REFRESH", this.onRefresh, this);
        MsgMgr.on("ON_"+this.name+"_SHOW", this.onEvtShow, this);
        MsgMgr.on("ON_"+this.name+"_RESHOW", this.onEvtReshow, this);
        MsgMgr.on("ON_"+this.name+"_HIDE", this.onEvtHide, this);
        MsgMgr.on("ON_"+this.name+"_CLOSE", this.onEvtClose, this);
        this.onRegEvent();
    }
    private removeEvent() {
        MsgMgr.off("ON_"+this.name+"_REFRESH", this.onRefresh, this);
        MsgMgr.off("ON_"+this.name+"_SHOW", this.onEvtShow, this);
        MsgMgr.off("ON_"+this.name+"_RESHOW", this.onEvtReshow, this);
        MsgMgr.off("ON_"+this.name+"_HIDE", this.onEvtHide, this);
        MsgMgr.off("ON_"+this.name+"_CLOSE", this.onEvtClose, this);
        this.onDelEvent();
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    //按钮点击通用
    protected on_click_common(button) {
        
    }

    //按钮touchstart
    protected on_click_common_start(button) {
    }

    //按钮touchcancel
    protected on_click_common_cancel(button) {

    }

    protected on_click_common_move(button) {

    }

    //打开界面的动作
    protected onShowAct() {
        // if (this._autoAdaptation) { 
        //     actEndCall && actEndCall();
        //     return;
        // }
        // cc.tween(this.node)
        //     .to(0.05, { scale: 1.1 })
        //     .to(0.05, { scale: 0.8 })
        //     .call(() => { actEndCall && actEndCall(); })
        //     .start()

        //actEndCall && actEndCall();
    }

    protected onCloseAct(actEndCall) {
        // if (this._autoAdaptation) { 
        //     actEndCall && actEndCall();
        //     return;
        // }
        // cc.tween(this.node)
        //     .to(0.1, { scale: 0.8 })
        //     .call(() => { actEndCall && actEndCall(); })
        //     .start()
        actEndCall && actEndCall();
        
    }

    protected onShow() {//显示回调 防止别人重写时忘记调用 把他设为私有
        this._isShow = true;
        if (this.node) {
            this.node.active = true;
        }
        MsgMgr.emit("ON_"+this.name+"_SHOW");
    }
    public onReshow(args) {//隐藏后重新显示
        this.onShow();
        this.onShowAct();
        MsgMgr.emit("ON_"+this.name+"_REFRESH");
    }
    public onHide() {//隐藏
        this._isShow = false;
        if (this.node) {
            this.node.active = false;
        }
        MsgMgr.emit("ON_"+this.name+"_HIDE");
    }
    public onClose() {//销毁
        this.closeMonitor();
        this.onCloseAct(function(){
            this.onHide();
            this.isGameCamerShow(true);
            if (this.node) {
                this.node.destroy();
            }
            this._isRemove = true;
            MsgMgr.emit("ON_"+this.name+"_CLOSE");
            this.removeEvent();

            if (this._isClearCache) {
                this.clearCache();
            }
        }.bind(this))
        
    }

    protected clearCache() {
        //依赖资源
        for (let i = 0; i < this._deps.length; i++) {
            let uuid = this._deps[i];
            let res = cc.assetManager.assets.get(uuid);
            res.decRef();
            res = null;
        }
    }

    public sleepTick(dt) {//隐藏的时候调用

    }

    protected onRefresh() {//事件触发刷新界面

    }

    ////////////////////////////////////////////////做界面需要重写的方法
    protected abstract prefab():string;
    public zOrder():number { return 0; }
    protected onRegEvent() {}   //自己添加监听事件
    protected onDelEvent() {}   //删除添加监听事件 有添加必须有删除
    protected onEvtShow() {}    //初始化显示事件
    protected onEvtReshow() {}  //重新显示界面事件
    protected onEvtHide() {}    //隐藏界面事件
    protected onEvtClose() {}   //销毁关闭界面事件
    public onUnfocus() {}       //取消关注
    public onFocus() {}         //关注
}
